/box-frame-create {                % =>
  box-container-create
  dup box-frame-setup-methods
  dup /box-frame add-type
} def

/box-frame-reflow {                % => Context Parent This
% If frame contains no boxes (for example, the src link is broken)
% we just return - no further processing will be done
  dup get-content length 0 gt {
      
% First box contained in a frame should always fill all its height
    dup get-height
    1 index get-content 0 get put-full-height

    0 3 index context-push-collapsed-margin
    dup get-uid 3 index context-push-container-uid
  
    2 index 1 index
    box-container-reflow-content

    2 index context-pop-collapsed-margin
    2 index context-pop-container-uid
  } if
  
  pop pop pop
} def

/box-frame-setup-methods {         % => Box
  dup /Methods get
  dup /reflow {box-frame-reflow} put
  pop pop
} def

/box-frameset-create {
  box-container-create
  dup box-frameset-setup-methods
  dup /rows 1 put
  dup /cols 1 put
  dup /box-frameset add-type
} def

/box-frameset-guess-lengths {      % => Height Lengths Frameset
% Initialization
  []                               % => Height Lengths Frameset Values
  2 index {                        % => Height Lengths Frameset Values Length
    pop 0 exch array-append        % => Height Lengths Frameset Values'
  } forall

% First pass: fixed-width columns
  0 1 2 index length 1 sub {       % => Height Lengths Frameset Values I
    3 index 1 index get
    dup /type get                  % => Height Lengths Frameset Values I Length Type
    {
      dup /percentage eq {
        pop
        /value get                 % => Height Lengths Frameset Values I Value
        5 index mul
        100 div                    % => Height Lengths Frameset Values I Value

        2 index 2 index 2 index put
        pop
        
        exit 
      } if

      dup /constant eq {
        pop

        /value get px              % => Height Lengths Frameset Values I Value
        2 index 2 index 2 index put

        pop
        exit
      } if
      
      pop pop exit
    } loop                         % => Height Lengths Frameset Values I
    pop                            % => Height Lengths Frameset Values
  } for                            % => Height Lengths Frameset Values

% Second pass: relative-width columns

  3 index 1 index sum sub          % => Height Lengths Frameset Values Rest

  0                                % => Height Lengths Frameset Values Rest Parts
  4 index 
  {                                % => Height Lengths Frameset Values Rest Parts Value
    dup /type get /fraction eq {   % => Height Lengths Frameset Values Rest Parts Value
      /value get add               % => Height Lengths Frameset Values Rest Parts
    } {                            % => Height Lengths Frameset Values Rest Parts Value
      pop
    } ifelse                       % => Height Lengths Frameset Values Rest Parts
  } forall

  dup 0 gt {
    div                            % => Height Lengths Frameset Values PartSize
    0 1 5 index length 1 sub {     % => Height Lengths Frameset Values PartSize I
      4 index 1 index get
      dup /type get /fraction eq { % => Height Lengths Frameset Values PartSize I Length
        /value get                 % => Height Lengths Frameset Values PartSize I Parts
        2 index mul                % => Height Lengths Frameset Values PartSize I Len
        3 index exch
        2 index exch put           % => Height Lengths Frameset Values PartSize I
      } {
        pop
      } ifelse                     % => Height Lengths Frameset Values PartSize I
      pop
    } for                          % => Height Lengths Frameset Values PartSize
    pop
  } { pop pop } ifelse             % => Height Lengths Frameset Values

% Fix over/underconstrained framesets
  dup sum                          % => Height Lengths Frameset Values Width
  dup 0 gt {
    4 index exch div               % => Height Lengths Frameset Values Koeff
    0 1 3 index length 1 sub {     % => Height Lengths Frameset Values Koeff I
      2 index 1 index get
      2 index mul                  % => Height Lengths Frameset Values Koeff I Value'
      3 index exch
      2 index exch put             % => Height Lengths Frameset Values Koeff I
      pop
    } for                          % => Height Lengths Frameset Values Koeff
    pop
  } {
    pop
  } ifelse

  exch pop
  exch pop
  exch pop
} def

/box-frameset-put-cols {           % => Value Box
  exch /cols exch put
} def

/box-frameset-put-rows {
  exch /rows exch put
} def

/box-frameset-reflow {             % => Context Parent Box
  2 index context-get-viewport     % => Context Parent Box Viewport

% Frameset always fill all available space in viewport

  dup flow-viewport-get-left
  2 index get-extra-left add
  2 index put-left

  dup flow-viewport-get-top
  2 index get-extra-top sub
  2 index put-top

  dup flow-viewport-get-width
  2 index put-full-width

  dup flow-viewport-get-height
  2 index put-full-height

  pop                              % => Context Parent Box 

% Parse layout-colntrol values
  dup get-height
  1 index /rows get
  2 index  
  box-frameset-guess-lengths       % => Context Parent Box RowSizes

  1 index /get-width call-method
  2 index /cols get
  3 index
  box-frameset-guess-lengths       % => Context Parent Box RowSizes ColSizes

% Now reflow all frames in frameset
  0 0                              % => Context Parent Box RowSizes ColSizes CurCol CurRow
  4 index get-content {            % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame
% Had we run out of cols/rows ?
    1 index 5 index length ge {
      pop
      exit
    } if                           % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

% Guess frame size and position
    5 index get-left               % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Left
    4 index 0                      % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Left ColsSizes 0
    5 index getinterval sum        % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Left ColOfs
    add
    1 index get-extra-left add     % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Left
    1 index put-left               % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

    5 index get-top                % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Top
    5 index 0
    4 index getinterval sum        % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Top RowOfs
    sub
    1 index get-extra-top sub
    1 index put-top                % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

    3 index 3 index get
    1 index put-full-width         % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

    dup /get-width call-method wc-create-constant
    1 index put-width-constraint

    4 index 2 index get
    1 index put-full-height        % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

% Reflow frame contents
    dup flow-viewport-create       % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame Viewport'
    8 index context-push-viewport  % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame
    
    7 index
    6 index
    2 index /reflow call-method    % => Context Parent Box RowSizes ColSizes CurCol CurRow Frame

    7 index context-pop-viewport

% Move to the nex frame position
    3 2 roll 1 add 3 1 roll        % => Context Parent Box RowSizes ColSizes CurCol' CurRow Frame
    2 index 4 index length ge {
      3 2 roll pop 0 3 1 roll
      exch 1 add exch
    } if
    
    pop
  } forall                         % => Context Parent Box RowSizes ColSizes CurCol CurRow

  pop pop pop pop
  pop pop pop
} def

/box-frameset-setup-methods {
  dup /Methods get
  dup /reflow {box-frameset-reflow} put
  pop pop
} def

